package com.yl.immodule;


import android.app.ActivityManager;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.media.MediaRecorder;
import android.os.Build;
import android.os.Process;
import android.util.Log;
import android.widget.Toast;

import androidx.annotation.RequiresApi;
import androidx.lifecycle.MutableLiveData;
import androidx.multidex.MultiDexApplication;

import com.camera.base.BaseApp;
import com.camera.base.bean.YLBean;
import com.yl.immodule.cc.CCHelper;
import com.yl.immodule.eventbus.CallAudioOutSideEvent;
import com.yl.immodule.eventbus.CallVideoOutSideEvent;
import com.yl.immodule.eventbus.LoginOutSideEvent;
import com.yl.immodule.v.AvActivity;
import com.android.yl.ylicpsdk.ICPRtc;
import com.android.yl.ylicpsdk.ICPRtcEventHandler;
import com.android.yl.ylicpsdk.ICPRtcManager;
import com.baidu.mapapi.SDKInitializer;
import com.hm.poc.chat.ChatMessageCategory;
import com.hm.poc.chat.ChatMessageStatus;
import com.unionbroad.greendao.ChatMessage;
import com.hm.poc.utils.ToastService;
import com.unionbroad.app.PocApplication;
import com.unionbroad.app.eventbus.ChannelChangedEvent;
import com.unionbroad.app.util.FileDownloadManager;
import com.unionbroad.app.util.Logger;
import com.unionbroad.app.util.UnionUtils;

import org.greenrobot.eventbus.EventBus;

import java.io.File;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;

public class APP extends MultiDexApplication {
    private Logger logger = Logger.getLogger("APP");
    private static MutableLiveData<Boolean> hasPermission = new MutableLiveData();
    public static void updatePermission(Boolean has) {
        hasPermission.postValue(has);
    }
    private ICPRtcEventHandler.IncomingInfo currentCallInfo;
    public static ToastService toastService = new ToastService();
    public BroadcastReceiver tempBoradCastReceiver;
    public BroadcastReceiver keyEventBoradCastReceiver;
    @RequiresApi(api = Build.VERSION_CODES.P)
    @Override
    public void onCreate() {
        super.onCreate();
        /** 防止反复初始化 */
        if (getPackageName() != null && getPackageName().equals(getCurrentProcessName(this))) {//android.os.Process.myPid()
            initBroadcast();
            ICPRtcManager.init(APP.this,getConfig());
            //可以在Application中监听，也可以在Service中监听，主要希望全局监听来电和新消息
            ICPRtcManager.getsInstance().addEventHandler(icpRtcEventHandler);
            tempBoradCastReceiver = new TempBroadCastRevicer();
            IntentFilter intentFilter = new IntentFilter();
            intentFilter.addAction("login");
            intentFilter.addAction("call_audio");
            intentFilter.addAction("call_video");
            registerReceiver(tempBoradCastReceiver,intentFilter);

            keyEventBoradCastReceiver = new KeyEventBroadCastRevicer();
            IntentFilter keyIntentFilter = new IntentFilter();
            if (BaseApp.ylBean.keyEvents.size() > 0) {
                for (YLBean.KeyEvent keyEvent: BaseApp.ylBean.keyEvents) {
                    if (keyEvent.todo.equals("pttDown") || keyEvent.todo.equals("pttUp")) {
                        keyIntentFilter.addAction(keyEvent.action);
                    }
                }
            }
            registerReceiver(keyEventBoradCastReceiver,keyIntentFilter);
        }
    }
    private String getCurrentProcessName(Context context) {
        int pid = Process.myPid();
        ActivityManager mActivityManager = (ActivityManager) context
                .getSystemService(Context.ACTIVITY_SERVICE);
        for (ActivityManager.RunningAppProcessInfo appProcess : mActivityManager
                .getRunningAppProcesses()) {
            if (appProcess.pid == pid) {
                return appProcess.processName;
            }
        }
        return null;
    }
    public static ICPRtc.Configure getConfig() {
        ICPRtc.Configure configure = ICPRtcProducer.getConfig();
        /** 可选配置 */
        //使用音乐通道
        configure.useMusicStream = false;
        configure.useHttps = true;
        //对讲录音
        configure.pttPlayback = true;

        //AI降噪
        configure.aiNoiseSuppression = false;

        //保活服务
        configure.keepLiveService = true;
        configure.keepLiveHeartbeat = 600;

        //联系人状态刷新时间间隔，单位秒
        configure.statusUpdateInterval = 120;

        configure.useExternalCamera = false;
        configure.useExternalCamera_V4l2 = false;
        configure.hardwareEncode = false;

        configure.disableInternalGpsFunc = false;
        configure.externalEncodeFrame = false;
        configure.externalFrameConsumer = false;

        //视频通话分辨率，需要和调度台中设置的值一样才能生效
        configure.videoResolution = ICPRtcEventHandler.VideoResolution.RESOLUTION_1920X1080;
        //渲染模式
        configure.videoRenderMode = ICPRtcEventHandler.VideoViewRenderMode.RENDER_MODE_ASPECT_FIT;

        configure.enableSoundTip = false;
        /*
        configure.useMusicStream = false;
        configure.audioAecLevel = ICPRtcEventHandler.AudioAecLevel.AEC_LEVEL_3;
        configure.audioAgcLevel = ICPRtcEventHandler.AudioAgcLevel.AGC_LEVEL_0;
        configure.audioNsLevel = ICPRtcEventHandler.AudioNsLevel.NS_LEVEL_3;
        if ("p999-xd".equals(Build.MODEL)) {
            //手持终端
            configure.audioSource = MediaRecorder.AudioSource.VOICE_COMMUNICATION;
        } else {
            //pad
            configure.audioSource = MediaRecorder.AudioSource.VOICE_COMMUNICATION;
            configure.pttAudioSource = MediaRecorder.AudioSource.MIC;
        }*/

        if (Build.MODEL.equalsIgnoreCase("cpu: mt6771 8 core 2.0ghz ram: 4g rom: 16g")) {
            configure.audioAecLevel = ICPRtcEventHandler.AudioAecLevel.AEC_LEVEL_2;
            configure.audioAgcLevel = ICPRtcEventHandler.AudioAgcLevel.AGC_LEVEL_DEFAULT;
            configure.audioNsLevel = ICPRtcEventHandler.AudioNsLevel.NS_LEVEL_2;
            int mic = MediaRecorder.AudioSource.MIC;
            configure.audioSource = mic;
            configure.pttAudioSource = mic;
            configure.useMusicStream = false;
        }
        configure.videoResolution = ICPRtcEventHandler.VideoResolution.RESOLUTION_1280X720;
        configure.defaultFrontCamera = true;
        configure.camera_hal_api_version_1_0 = true;
        configure.frontCameraId = 0;

        configure.hardwareEncode = true;

        //缓存提供器，没特殊要求用不到
        //configure.cacheFileSupplier = cacheFileSupplier;
        //侧边功能键注册，一般都用不到
        //configure.broadcastHotKeyActionSupplier = hotKeyActionSupplier;
        //其它...
        return configure;
    }

    /**
     * 目前配置项较多，很多配置没有单独的设置接口，建议全局保持一个Configure，
     * 确保每次 ICPRtcProducer.get().config()时，设置进去的配置项都是有效值
     */
    public static class ICPRtcProducer {
        static ICPRtc.Configure configure;
        public static ICPRtc.Configure getConfig() {
            if (configure == null) {
                configure = new ICPRtc.Configure();
//                configure.ip = "121.40.230.149";
//                configure.port = "6050";
//                configure.httpPort = "80";
                configure.ip = "icp.zhifapingtai.com";
                configure.port = "6050";
                configure.httpPort = "80";
                configure.useNewServer = true; //php服务器设置为false, java服务器设置为true

//                configure.ip = "47.88.172.189";
//                configure.port = "5060";
//                configure.httpPort = "80";
            }
            return configure;
        }
    }



    private SDKReceiver mReceiver;
    private void initBroadcast() {
        IntentFilter iFilter = new IntentFilter();
        iFilter.addAction(SDKInitializer.SDK_BROADTCAST_ACTION_STRING_PERMISSION_CHECK_OK);
        iFilter.addAction(SDKInitializer.SDK_BROADTCAST_ACTION_STRING_PERMISSION_CHECK_ERROR);
        iFilter.addAction(SDKInitializer.SDK_BROADCAST_ACTION_STRING_NETWORK_ERROR);
        mReceiver = new SDKReceiver();
        registerReceiver(mReceiver, iFilter);
    }

    //定位模块状态通知
    public class SDKReceiver extends BroadcastReceiver {
        public void onReceive(Context context, Intent intent) {
            String s = intent.getAction();
            logger.d("SDKReceiver: " + s);
            if (s.equals(SDKInitializer.SDK_BROADTCAST_ACTION_STRING_PERMISSION_CHECK_ERROR)) {
                logger.d("key 验证出错! 错误码");
            } else if (s.equals(SDKInitializer.SDK_BROADTCAST_ACTION_STRING_PERMISSION_CHECK_OK)) {
                logger.d("key 验证成功! 功能可以正常使用");
            } else if (s.equals(SDKInitializer.SDK_BROADCAST_ACTION_STRING_NETWORK_ERROR)) {
                logger.d("网络出错");
            }
        }
    }
    public class KeyEventBroadCastRevicer extends BroadcastReceiver{

        @Override
        public void onReceive(Context context, Intent intent) {
            if (BaseApp.ylBean.keyEvents.size() > 0) {
                for (YLBean.KeyEvent keyEvent: BaseApp.ylBean.keyEvents) {
                    if (intent.getAction().equals(keyEvent.action)){
                        if (keyEvent.todo.equals("pttDown")){
                            //PTT按下
                            Log.e("TAG", "pttDown: " );
                            ICPRtcManager.getsInstance().applyPttSpeak();
                        }else if (keyEvent.todo.equals("pttUp")){
                            //PTT抬起
                            Log.e("TAG", "pttUp: " );
                            ICPRtcManager.getsInstance().freePttSpeak();
                        }
                    }
                }
            }
        }
    }

    private final ICPRtcEventHandler icpRtcEventHandler = new ICPRtcEventHandler() {


        @Override
        public void onMessageReceived(long chatId, List<ChatMessage> messages) {
            logger.d("onMessageReceived-> " + chatId + " size=" + messages.size());

            //收到新的消息
            if (messages != null && messages.size() > 0) {
                //仅为调试，只取出其中一条
                ChatMessage message = messages.get(0);
                //语音通话记录
                if (message.getCategory() == ChatMessageCategory.AUDIO) {
                    logger.i("==> 语音通话记录");
                }
                //视频通话记录
                else if (message.getCategory() == ChatMessageCategory.VIDEO) {
                    logger.i("==> 视频通话记录");
                }
                //语音广播
                else if (message.getCategory() == ChatMessageCategory.AUDIO_BROADCAST) {
                    logger.i("==> 语音广播");
                }
                //语音文件，类似微信的语音消息
                else if (message.getCategory() == ChatMessageCategory.AUDIO_FILE) {
                    logger.i("==> 语音消息");
                }
                //对讲录音，只有开启对讲回放功能，每次有人讲话时，才会把声音录制下来
                else if (message.getCategory() == ChatMessageCategory.PTT_AUDIO_FILE) {
                    logger.i("==> 对讲录音消息 " + message.getRemote_number() + " "
                            + message.getRemote_name() + " isOut=" + message.getIs_out());
                }
                //视频消息，类似微信的视频消息
                else if (message.getCategory() == ChatMessageCategory.VIDEO_FILE) {
                    logger.i("==> 视频消息: " + message.getDownload_status());
                    switch (message.getDownload_status()) {
                        case ChatMessageStatus.File.DOWN_SUCCESSED:
                            message.setDownload_status(ChatMessageStatus.File.DOWN_SUCCESSED);
                            //play
                            break;
                        case ChatMessageStatus.File.DOWN_UNINIT:
                            message.setDownload_status(ChatMessageStatus.File.DOWN_STARTING);
                            FileDownloadManager.getInstance().startDownTask(message.getId(), message.getHttpFile(), message.getLocalFile());
                            //使用EventBus监听ChatFileDownloadCompletedEvent，获取文件下载结果
                            break;
                    }
                }
                //图片消息
                else if (message.getCategory() == ChatMessageCategory.IMAGE) {
                    logger.i("==> 图片消息");
                }
                //位置消息
                else if (message.getCategory() == ChatMessageCategory.LOCATION) {
                    logger.i("==> 位置消息");
                }
                //文字消息
                else if (message.getCategory() == ChatMessageCategory.TEXT) {
                    logger.i("==> 文字消息: " + message.getText());
                }

                //================以下两种消息，如果业务需求，可以放到动态页中去=========================
                //拍传@消息
                else if (message.getCategory() == ChatMessageCategory.NOTIFICATION_REPORT) {
                    logger.i("==> 拍传@消息");
                }
                //报警消息
                else if (message.getCategory() == ChatMessageCategory.ALERT) {
                    logger.i("==> 报警消息: " + message.getText());
                }
                //任务消息
                else if (message.getCategory() == ChatMessageCategory.NOTIFICATION_TASK) {
                    logger.i("==> 任务消息: " + message.getText());
                }
                //==================================================================================

                //其它消息一般用不到
                else {
                    logger.i("==> 其它消息: " + message.getText());
                }
            }
        }

        @Override
        public void onIncoming(IncomingInfo incomingInfo) {
            logger.d("onIncoming-> sessionId=" + incomingInfo.sessionId + " type=" + incomingInfo.sessionType + " uid=" +
                    incomingInfo.callerId + " name=" + incomingInfo.callerName + " level=" + incomingInfo.level +
                    " extra=" + incomingInfo.extra);

            // 当前会诊业务模式
            if (CCHelper.isCcBzMode) {
                CCHelper.INSTANCE.handlerCCIncoming(getApplicationContext(), incomingInfo);
                return;
            }

            if (APP.this.currentCallInfo != null) {
                // 已有来电，挂断新的
                ICPRtcManager.getsInstance().hangUpCall(incomingInfo.sessionId);
                Toast.makeText(getApplicationContext(), "强制挂断新的来电", Toast.LENGTH_SHORT).show();
                return;
            }

            APP.this.currentCallInfo = incomingInfo;
            if (incomingInfo.sessionType == SessionType.TYPE_VIDEO_MONITOR_CALL) {
                ICPRtcManager.getsInstance().acceptCall(incomingInfo.sessionId);
            } else {
                Intent intent = new Intent(APP.this, AvActivity.class);
                intent.putExtra("sessionId", incomingInfo.sessionId);
                intent.putExtra("callerId", incomingInfo.callerId);
                intent.putExtra("callerName", incomingInfo.callerName);
                intent.putExtra("type", incomingInfo.sessionType);
                intent.putExtra("extra", incomingInfo.extra);
                intent.putExtra("isIncomingCall", true);
                intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                APP.this.startActivity(intent);
            }
        }

        @Override
        public void onIgnoreIncoming(int sessionType, long callerId) {
            super.onIgnoreIncoming(sessionType, callerId);
            logger.i("onIgnoreIncoming sessionType=" + sessionType + ", callerId=" + callerId);
        }

        @Override
        public void onCallDisconnected(long sessionId, int reason) {
            logger.i("onCallDisconnected sessionId=" + sessionId + ", reason=" + reason);
            if (currentCallInfo != null && currentCallInfo.sessionId == sessionId) {
                logger.i("onCallDisconnected currentCallInfo=" + currentCallInfo);
                currentCallInfo = null;
            }
        }

        @Override
        public void onChannelChangedEvent(ChannelChangedEvent event) {
            Toast.makeText(getApplicationContext(), "onChannelChangedEvent", Toast.LENGTH_SHORT).show();
        }

        @Override
        public boolean onForcedOffline() {
            //True: 响应了下线事件，False：没有响应，sdk内部会弹出对话框，禁止再操作
            Toast.makeText(getApplicationContext(), "onForcedOffline", Toast.LENGTH_SHORT).show();
            return false;
        }

        @Override
        public void onBackstageMonitorAction(int action, long sessionId, String monitorUid, boolean isVideoMonitor) {
            logger.i("onBackstageMonitorAction: action=" + action);
        }

        @Override
        public void onReceiveLocation(double latitude, double longitude, String address) {
            Toast.makeText(getApplicationContext(), "坐标变化(" + latitude + "," + longitude + ")", Toast.LENGTH_SHORT).show();
        }


        @Override
        public void onRequestCamera() {
            logger.d("onRequestCamera");
        }

        @Override
        public void onReleaseCamera() {
            logger.d("onReleaseCamera");
        }

        @Override
        public void onRequestMic() {
            logger.d("onRequestMic");
        }

        @Override
        public void onReleaseMic() {
            logger.d("onReleaseMic");
        }

        @Override
        public void onVideoStreamTakePictureFinish(String filePath) {
            Toast.makeText(getApplicationContext(), "拍照已保存到: " + filePath, Toast.LENGTH_SHORT).show();
        }
    };

    /**
     * 缓存文件路径及格式提供器
     */
    private final ICPRtcEventHandler.CacheFileSupplier cacheFileSupplier = new ICPRtcEventHandler.CacheFileSupplier() {
        @Override
        public String getBaseDir() {
            //TODO 返回一个缓存根目录路径，需要创建
            return null;
        }

        @Override
        public String getFileNameExpansion() {
            //TODO 返回扩展文件名，即 用户id + ????? + .格式 中问号这一段，缺省时，会按照日期的格式
            return null;
        }

        /**
         * 每需要缓存一个文件时，会调用一次这个接口，根据后缀返回相应的全路径，路径要创建好
         * @param fileFormat 文件后缀
         * @return
         */
        @Override
        public String getFullCacheFilePath(String fileFormat) {
            String baseCache;
            if (fileFormat.contains("3pg") || fileFormat.contains("mp4")) {
                baseCache = UnionUtils.getVideoCachePath();
            } else if (fileFormat.contains("jpg") || fileFormat.contains("png")) {
                baseCache = UnionUtils.getPicCachePath();
            } else if (fileFormat.contains("raw") || fileFormat.contains("wav")
                    || fileFormat.contains("amr") || fileFormat.contains("mp3")) {
                baseCache = UnionUtils.getAudioFileCachePath();
            } else {
                baseCache = UnionUtils.getBaseCachePath();
            }

            Date date = new Date();
            String ymd = new SimpleDateFormat("yyyyMMdd").format(date);
            String saveDir = baseCache + File.separator + ymd;
            File dir = new File(saveDir);
            if (!dir.exists()) {
                dir.mkdir();
            }
            StringBuilder builder = new StringBuilder();
            builder.append(PocApplication.sUserNumber);
            builder.append("_");
            builder.append(ymd);
            builder.append("_");
            builder.append("test");
            builder.append(fileFormat);
            String fileName = builder.toString();

            String path = new File(saveDir, fileName).getPath();
            return path;
        }
    };

    public class TempBroadCastRevicer extends BroadcastReceiver{

        @Override
        public void onReceive(Context context, Intent intent) {
            String action = intent.getAction();
            if (action.equals("login")){
                String acc = intent.getStringExtra("account");
                String psw = intent.getStringExtra("password");
                EventBus.getDefault().post(new LoginOutSideEvent(acc,psw));
            }else if(action.equals("call_audio")){
                String userId = intent.getStringExtra("userId");
                EventBus.getDefault().post(new CallAudioOutSideEvent(userId));
            }else if(action.equals("call_video")){
               String userId = intent.getStringExtra("userId");

                EventBus.getDefault().post(new CallVideoOutSideEvent(userId));
            }
        }
    }
}
